package com.flame.core.mybatis;

import java.util.List;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

/**
 * FlamePageInterceptor
 *
 * @author wuxintong
 * @since 2022/9/11
 */
@Intercepts({@Signature(type = Executor.class, method = "query",
    args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
    @Signature(type = Executor.class, method = "query",
        args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class,
            BoundSql.class})})
public class FlamePageInterceptor implements Interceptor {

    private static final String ORDER_BY_FORMATE = "%s %s";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        if (args != null && args.length > 0) {
            if (List.class.equals(invocation.getMethod().getReturnType()) && args[1] instanceof PageParam) {
                PageParam pageParam = (PageParam) args[1];
                int pageNum = pageParam.getPageNum();
                int pageSize = pageParam.getPageSize();
                if (pageNum == 0 && pageSize == 0) {
                    return invocation.proceed();
                }

                PageHelper.startPage(pageNum, pageSize);
                Object proceed = invocation.proceed();
                if (proceed instanceof Page) {
                    Page res = (Page) proceed;
                    return new PageList<>(res.getResult(), res.getPageNum(), res.getPageSize(), res.getPages(),
                        res.getTotal());
                }
            }
        }
        return invocation.proceed();
    }
}
